import { useNRTCHK } from '@/hooks/rtc'
import { NRTC, TRACK_TYPE, TYPE, type NotifyResponse } from 'nrtc-web'
import { useToast } from '@/lib'

export const useRoomRTC = () => {
  const nrtc = inject<NRTC>('nrtc')
  const { createToast, addToast } = useToast()
  const loading = ref({
    mic: false,
    camera: false,
    screen: false
  })

  const [openModal, toggleModal] = useToggle(false)
  const modal = ref<HTMLDialogElement>()

  const videoView = ref<HTMLElement>()
  const screenView = ref<HTMLElement>()
  const refs = useTemplateRefsList<HTMLDivElement>()

  const { ready, publish, streams, microphone, camera, speaker } = useNRTCHK()

  const leaveRoom = async () => {
    await nrtc?.exitRoom()
  }

  const toggleLocalAudio = async () => {
    loading.value.mic = true
    if (ready.value.audio) {
      await nrtc?.stopLocalAudio()
      ready.value.audio = publish.value.audio = false
      streams.audio = null
    } else {
      const stream = await nrtc?.startLocalAudio({
        publish: true,
        option: {
          micphoneId: microphone.value?.deviceId
        }
      })

      if (stream instanceof MediaStream) {
        ready.value.audio = true
        streams.audio = stream
        stream.onaddtrack = (ev: MediaStreamTrackEvent) => {
          console.log('onaddtrack', ev.track)
        }
        const [track] = stream.getAudioTracks()
        track.onended = () => {
          ready.value.audio = publish.value.audio = false
          streams.audio = null
        }
        publish.value.audio = true
      }
    }

    loading.value.mic = false
  }

  const toggleLocalVideo = async () => {
    loading.value.camera = true
    if (ready.value.video) {
      await nrtc?.stopLocalVideo()
      ready.value.video = publish.value.video = false
      streams.video = null
    } else {
      const stream = await nrtc?.startLocalVideo({
        publish: true,
        option: {
          cameraId: camera.value?.deviceId
        }
      })

      console.log('toggleLocalVideo', stream)

      if (stream instanceof MediaStream) {
        ready.value.video = true
        nextTick(() => {
          nrtc?.updateLocalVideo({
            view: videoView.value
          })
        })
        stream.onaddtrack = (ev: MediaStreamTrackEvent) => {
          console.log('onaddtrack', ev.track)
        }
        const [track] = stream.getTracks()
        track.onended = () => {
          ready.value.video = publish.value.video = false
          streams.video = null
        }

        streams.video = stream

        publish.value.video = true
      }
    }

    loading.value.camera = false
  }

  const toggleLocalScreen = async () => {
    loading.value.screen = true
    if (ready.value.ScreenVideo || ready.value.ScreenAudio) {
      await nrtc?.stopLocalScreenShare()
      ready.value.ScreenVideo = publish.value.ScreenVideo = false
      ready.value.ScreenAudio = publish.value.ScreenAudio = false
      streams.screen = null
    } else {
      const stream = await nrtc?.startLocalScreenShare({
        publish: true
      })

      if (stream instanceof MediaStream) {
        ready.value.ScreenVideo = publish.value.ScreenVideo = true
        ready.value.ScreenAudio = publish.value.ScreenAudio = true
        streams.screen = stream

        nextTick(() => {
          nrtc?.updateLocalScreenShare({
            view: screenView.value
          })
        })

        const [videoTrack] = stream.getVideoTracks()
        videoTrack.onended = () => {
          ready.value.ScreenVideo = publish.value.ScreenVideo = false
          ready.value.ScreenAudio = publish.value.ScreenAudio = false
          streams.screen = null
        }
      }
    }
  }

  const switchMic = async (deviceId: string) => {
    if (ready.value.audio) {
      const error = await nrtc?.updateLocalAudio({
        option: {
          micphoneId: deviceId
        }
      })

      if (error instanceof Error) {
        console.log('error', error)
        switch (error.name) {
          case 'NotAllowedError':
            addToast(createToast({ message: '不允许的设备' }))
            break
          case 'NotFoundError':
            addToast(createToast({ message: '没找到对应设备' }))
            break
          case 'AbortError':
            addToast(createToast({ message: '设备异常' }))
            break
        }
      }
    }
  }

  const switchSpeaker = async (deviceId: string) => {
    await NRTC.setCurrentSpeaker(deviceId)
    speaker.value
  }

  const switchCamera = (deviceId: string) => {
    if (ready.value.video) {
      nrtc?.updateLocalVideo({
        option: {
          cameraId: deviceId
        }
      })
    }
  }

  const requestConsumer = async (producer: NotifyResponse.newProducer) => {
    console.log('producer', producer)
    switch (producer.kind) {
      case TRACK_TYPE.VIDEO:
        const data = await nrtc?.startRemoteVideo({
          producerId: producer.producerId
        })
        console.log('data', data)
        break
      case TRACK_TYPE.AUDIO:
        nrtc?.muteRemoteAudio({
          producerId: producer.producerId,
          mute: false
        })
        break
    }
  }

  const openConsumerInfo = (item?: any, open?: boolean) => {
    if (open) {
      modal.value?.showModal()
    } else {
      modal.value?.close()
    }
  }

  return {
    refs,

    modal,
    toggleModal,

    videoView,
    screenView,
    leaveRoom,

    switchMic,
    switchSpeaker,
    switchCamera,

    toggleLocalAudio,
    toggleLocalVideo,
    toggleLocalScreen,

    requestConsumer,
    openConsumerInfo,
  }
}
